home *** CD-ROM | disk | FTP | other *** search
/ Programming an RTS Game with Direct3D / Programming an RTS Game with Direct3D.iso / Examples / Chapter 12 / Example 12.8 / app.cpp next >
Encoding:
C/C++ Source or Header  |  2006-08-01  |  7.6 KB  |  304 lines

  1. //////////////////////////////////////////////////////////////
  2. // Example 12.8: The Roof, the Roof, the Roof is on Fire...    //
  3. // Written by: C. Granberg, 2006                            //
  4. //////////////////////////////////////////////////////////////
  5.  
  6. #include <windows.h>
  7. #include <d3dx9.h>
  8. #include <vector>
  9. #include "debug.h"
  10. #include "effect.h"
  11. #include "mesh.h"
  12. #include "camera.h"
  13. #include "particles.h"
  14.  
  15. extern std::vector<EFFECT*> effects;
  16.  
  17. class APPLICATION
  18. {
  19.     public:
  20.         APPLICATION();
  21.         HRESULT Init(HINSTANCE hInstance, int width, int height, bool windowed);
  22.         HRESULT Update(float deltaTime);
  23.         HRESULT Render();
  24.         HRESULT Cleanup();
  25.         HRESULT Quit();
  26.         DWORD FtoDword(float f){return *((DWORD*)&f);}
  27.  
  28.     private:
  29.         IDirect3DDevice9* m_pDevice; 
  30.         MESH m_building;
  31.         CAMERA m_camera;
  32.  
  33.         DWORD m_time;
  34.         int m_fps, m_lastFps;
  35.         D3DLIGHT9 m_light;
  36.         HWND m_mainWindow;
  37.         ID3DXFont *m_pFont;
  38. };
  39.  
  40. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance, PSTR cmdLine, int showCmd)
  41. {
  42.     APPLICATION app;
  43.  
  44.     if(FAILED(app.Init(hInstance, 800, 600, true)))return 0;
  45.  
  46.     MSG msg;
  47.     memset(&msg, 0, sizeof(MSG));
  48.     int startTime = timeGetTime(); 
  49.  
  50.     while(msg.message != WM_QUIT)
  51.     {
  52.         if(::PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
  53.         {
  54.             ::TranslateMessage(&msg);
  55.             ::DispatchMessage(&msg);
  56.         }
  57.         else
  58.         {    
  59.             int t = timeGetTime();
  60.             float deltaTime = (t - startTime)*0.001f;
  61.  
  62.             app.Update(deltaTime);
  63.             app.Render();
  64.  
  65.             startTime = t;
  66.         }
  67.     }
  68.  
  69.     app.Cleanup();
  70.  
  71.     return msg.wParam;
  72. }
  73.  
  74. APPLICATION::APPLICATION()
  75. {
  76.     m_pDevice = NULL; 
  77.     m_mainWindow = 0;
  78.     srand(GetTickCount());
  79.  
  80.     m_fps = m_lastFps = 0;
  81.     m_time = GetTickCount();
  82. }
  83.  
  84. HRESULT APPLICATION::Init(HINSTANCE hInstance, int width, int height, bool windowed)
  85. {
  86.     debug.Print("Application initiated");
  87.  
  88.     //Create Window Class
  89.     WNDCLASS wc;
  90.     memset(&wc, 0, sizeof(WNDCLASS));
  91.     wc.style         = CS_HREDRAW | CS_VREDRAW;
  92.     wc.lpfnWndProc   = (WNDPROC)::DefWindowProc; 
  93.     wc.hInstance     = hInstance;
  94.     wc.lpszClassName = "D3DWND";
  95.  
  96.     //Register Class and Create new Window
  97.     RegisterClass(&wc);
  98.     m_mainWindow = CreateWindow("D3DWND", "Example 12.8: The Roof, the Roof, the Roof is on Fire...", WS_EX_TOPMOST, 0, 0, width, height, 0, 0, hInstance, 0); 
  99.     SetCursor(NULL);
  100.     ShowWindow(m_mainWindow, SW_SHOW);
  101.     UpdateWindow(m_mainWindow);
  102.  
  103.     //Create IDirect3D9 Interface
  104.     IDirect3D9* d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
  105.  
  106.     if(d3d9 == NULL)
  107.     {
  108.         debug.Print("Direct3DCreate9() - FAILED");
  109.         return E_FAIL;
  110.     }
  111.  
  112.     //Check that the Device supports what we need from it
  113.     D3DCAPS9 caps;
  114.     d3d9->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &caps);
  115.  
  116.     //Hardware Vertex Processing or not?
  117.     int vp = 0;
  118.     if(caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT)
  119.         vp = D3DCREATE_HARDWARE_VERTEXPROCESSING;
  120.     else vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
  121.  
  122.     //Check vertex & pixelshader versions
  123.     if(caps.VertexShaderVersion < D3DVS_VERSION(2, 0) || caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
  124.     {
  125.         debug.Print("Warning - Your graphic card does not support vertex and pixelshaders version 2.0");
  126.     }
  127.  
  128.     //Set D3DPRESENT_PARAMETERS
  129.     D3DPRESENT_PARAMETERS d3dpp;
  130.     d3dpp.BackBufferWidth            = width;
  131.     d3dpp.BackBufferHeight           = height;
  132.     d3dpp.BackBufferFormat           = D3DFMT_A8R8G8B8;
  133.     d3dpp.BackBufferCount            = 1;
  134.     d3dpp.MultiSampleType            = D3DMULTISAMPLE_NONE;
  135.     d3dpp.MultiSampleQuality         = 0;
  136.     d3dpp.SwapEffect                 = D3DSWAPEFFECT_DISCARD; 
  137.     d3dpp.hDeviceWindow              = m_mainWindow;
  138.     d3dpp.Windowed                   = windowed;
  139.     d3dpp.EnableAutoDepthStencil     = true; 
  140.     d3dpp.AutoDepthStencilFormat     = D3DFMT_D24S8;
  141.     d3dpp.Flags                      = 0;
  142.     d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
  143.     d3dpp.PresentationInterval       = D3DPRESENT_INTERVAL_IMMEDIATE;
  144.  
  145.     //Create the IDirect3DDevice9
  146.     if(FAILED(d3d9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, m_mainWindow,
  147.                                  vp, &d3dpp, &m_pDevice)))
  148.     {
  149.         debug.Print("Failed to create IDirect3DDevice9");
  150.         return E_FAIL;
  151.     }
  152.  
  153.     //Release IDirect3D9 interface
  154.     d3d9->Release();
  155.  
  156.     // Create m_light
  157.     ::ZeroMemory(&m_light, sizeof(m_light));
  158.     m_light.Type      = D3DLIGHT_DIRECTIONAL;
  159.     m_light.Ambient   = D3DXCOLOR(0.5, 0.5, 0.5, 1.0f);
  160.     m_light.Diffuse   = D3DXCOLOR(0.9, 0.9, 0.9, 1.0f);
  161.     m_light.Specular  = D3DXCOLOR(0.5, 0.5, 0.5, 1.0f);
  162.     D3DXVECTOR3 dir = D3DXVECTOR3(-1.0f, -1.0f, 0.0f);
  163.     D3DXVec3Normalize(&dir, &dir);
  164.     m_light.Direction = dir;    
  165.     m_pDevice->SetLight(0, &m_light);
  166.     m_pDevice->LightEnable(0, true);
  167.  
  168.     D3DXCreateFont(m_pDevice, 18, 0, 0, 1, false,  
  169.                    DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY,
  170.                    DEFAULT_PITCH | FF_DONTCARE, "Arial", &m_pFont);
  171.  
  172.     LoadEffectResources(m_pDevice);
  173.     LoadParticleResources(m_pDevice);
  174.  
  175.     //Add fires    
  176.     effects.push_back(new EFFECT_FIRE(m_pDevice, D3DXVECTOR3(0.0f, 25.0f, -5.0f), D3DXVECTOR3(25.0f, 25.0f, 25.0f)));
  177.     effects.push_back(new EFFECT_FIRE(m_pDevice, D3DXVECTOR3(-17.0f, 5.0f, -5.0f), D3DXVECTOR3(15.0f, 15.0f, 30.0f)));
  178.     effects.push_back(new EFFECT_FIRE(m_pDevice, D3DXVECTOR3(15.0f, 0.0f, 7.0f), D3DXVECTOR3(20.0f, 20.0f, 25.0f)));    
  179.  
  180.     m_building.Load("meshes/townhall.x", m_pDevice);
  181.  
  182.     m_camera.Init(m_pDevice);
  183.     m_camera.m_radius = 100.0f;
  184.     m_camera.m_fov = D3DX_PI * 0.25f;
  185.     m_camera.m_focus = D3DXVECTOR3(0.0f, 25.0f, 0.0f);
  186.     m_camera.m_beta = 0.5f;
  187.  
  188.     //Set sampler state
  189.     for(int i=0;i<4;i++)
  190.     {
  191.         m_pDevice->SetSamplerState(i, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
  192.         m_pDevice->SetSamplerState(i, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
  193.         m_pDevice->SetSamplerState(i, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
  194.     }
  195.  
  196.     return S_OK;
  197. }
  198.  
  199. HRESULT APPLICATION::Update(float deltaTime)
  200. {
  201.     m_camera.Update(deltaTime);
  202.  
  203.     //Remove dead effects
  204.     std::vector<EFFECT*>::iterator i;
  205.     for(i=effects.begin();i != effects.end();)
  206.     {
  207.         if((*i)->isDead())
  208.         {
  209.             delete (*i);
  210.             effects.erase(i);
  211.         }
  212.         else 
  213.         {
  214.             (*i)->Update(deltaTime);
  215.             i++;
  216.         }
  217.     }
  218.  
  219.     //Keayboard input
  220.     if(KEYDOWN(VK_SPACE))
  221.     {
  222.     }
  223.     if(KEYDOWN(VK_RETURN))
  224.     {
  225.     }
  226.     else if(KEYDOWN(VK_ESCAPE))
  227.     {
  228.         Quit();
  229.     }
  230.  
  231.     return S_OK;
  232. }    
  233.  
  234. HRESULT APPLICATION::Render()
  235. {
  236.     //FPS Calculation
  237.     m_fps++;
  238.     if(GetTickCount() - m_time > 1000)
  239.     {
  240.         m_lastFps = m_fps;
  241.         m_fps = 0;
  242.         m_time = GetTickCount();
  243.     }
  244.  
  245.     // Clear the viewport
  246.     m_pDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
  247.  
  248.     D3DXMATRIX identity;
  249.     D3DXMatrixIdentity(&identity);
  250.     m_pDevice->SetTransform(D3DTS_WORLD, &identity);
  251.  
  252.  
  253.     // Begin the scene 
  254.     if(SUCCEEDED(m_pDevice->BeginScene()))
  255.     {
  256.         m_building.Render();
  257.  
  258.         //Render Effects
  259.         for(int i=0;i<effects.size();i++)
  260.             if(effects[i] != NULL)
  261.                 effects[i]->Render();
  262.  
  263.         RECT r[] = {{10, 10, 0, 0}, {720, 10, 0, 0}};
  264.         m_pFont->DrawText(NULL, "Arrows: Rotate Camera", -1, &r[0], DT_LEFT| DT_TOP | DT_NOCLIP, 0xffffffff);
  265.         
  266.         //FPS
  267.         char number[50];
  268.         std::string text = "FPS: ";
  269.         text += _itoa(m_lastFps, number, 10);
  270.         m_pFont->DrawText(NULL, text.c_str(), -1, &r[1], DT_LEFT| DT_TOP | DT_NOCLIP, 0xffffffff);
  271.  
  272.         // End the scene.
  273.         m_pDevice->EndScene();
  274.         m_pDevice->Present(0, 0, 0, 0);
  275.     }
  276.  
  277.     return S_OK;
  278. }
  279.  
  280. HRESULT APPLICATION::Cleanup()
  281. {
  282.     try
  283.     {
  284.         UnloadEffectResources();
  285.         UnloadParticleResources();
  286.  
  287.         m_building.Release();
  288.  
  289.         m_pFont->Release();
  290.         m_pDevice->Release();
  291.  
  292.         debug.Print("Application terminated");
  293.     }
  294.     catch(...){}
  295.  
  296.     return S_OK;
  297. }
  298.  
  299. HRESULT APPLICATION::Quit()
  300. {
  301.     ::DestroyWindow(m_mainWindow);
  302.     ::PostQuitMessage(0);
  303.     return S_OK;
  304. }